#pragma once


#include<iostream>
#include"Socket.hpp"
#include"Log.hpp"
#include <sys/select.h>
#include <sys/time.h>
#include<vector>

using namespace std;

const uint16_t defalut=9998;
const int fd_num_max=sizeof(fd_set)*8;//字节大小×8比特位，最多关注文件描述符大小
int defaultfd=-1;
class SelectServe
{
public:
    SelectServe(uint16_t port=defalut):port_(port)
    {
        for(int i=0;i<fd_num_max;i++)
        {
            fd_arry[i]=defaultfd;
            // cout << "fd_arry[" << i << "]" << " : " << fd_arry[i] << std::endl;
        }
    }
    void Init()
    {
        listensock_.Socket();
        listensock_.Bind(port_);
        listensock_.Listen();
    }
    void Accepter()
    {
            string clientip;
            uint16_t port=defalut;
            int sockfd=listensock_.Accept(clientip,port);
            int i=0;
            for(i=0;i<fd_num_max;i++)
            {
                if(fd_arry[i]!=defaultfd) continue;
                else break;
            }
            if(i==fd_num_max)
            {
            lg(Warning, "server is full, close %d now!", sockfd);
            close(sockfd);
            }
            else
            {
                fd_arry[i]=sockfd;
                client_ips[i] = clientip;  // 保存客户端IP
                client_ports[i] = port;    // 保存客户端端口
                PrintFd();
            }
    }
    void Recver(int fd)
    {
        char buf[1024];
                ssize_t n = read(fd, buf, sizeof(buf)-1);
            if(n > 0)
            {
                buf[n] = '\0';
                cout << "收到来自客户端的数据：" << buf << endl;
            }
            else if(n == 0)
            {
                // 客户端关闭连接
                cout << "客户端关闭连接,fd=" << fd << endl;
                close(fd);
                fd = defaultfd;
            }
            else
            {
                // 读错误
                cerr << "read error" << endl;
                close(fd);
                fd = defaultfd;
            }
    }
    void Handler(fd_set& rfds)//派发
    {
        for(int i=0;i<fd_num_max;i++)//循环确定那个就绪,值判断了监听套接字就绪
        {
        int fd=fd_arry[i];
        if(fd==defaultfd) continue;
        if(FD_ISSET(fd,&rfds)>0)
        {
            if(fd==listensock_.Fd())//获取新连接，把sockfd加到数组
            {
                Accepter();//连接管理
            // string clientip;
            // uint16_t port=defalut;
            // int sockfd=listensock_.Accept(clientip,port);
            // int i=0;
            // for(i=0;i<fd_num_max;i++)
            // {
            //     if(fd_arry[i]!=defaultfd) continue;
            //     else break;
            // }
            // if(i==fd_num_max)
            // {
            // lg(Warning, "server is full, close %d now!", sockfd);
            // close(sockfd);
            // }
            // else
            // {
            //     fd_arry[i]=sockfd;
            //     client_ips[i] = clientip;  // 保存客户端IP
            //     client_ports[i] = port;    // 保存客户端端口
            //     PrintFd();
            // }
            }
            else//不是监听，sockfd就绪可以读了
            {
                Recver(fd_arry[i]);
            //     char buf[1024];
            //     ssize_t n = read(fd_arry[i], buf, sizeof(buf)-1);
            // if(n > 0)
            // {
            //     buf[n] = '\0';
            //     cout << "收到来自客户端的数据：" << buf << endl;
            // }
            // else if(n == 0)
            // {
            //     // 客户端关闭连接
            //     cout << "客户端关闭连接,fd=" << fd_arry[i] << endl;
            //     close(fd_arry[i]);
            //     fd_arry[i] = defaultfd;
            // }
            // else
            // {
            //     // 读错误
            //     cerr << "read error" << endl;
            //     close(fd_arry[i]);
            //     fd_arry[i] = defaultfd;
            // }
            }
        }
        }
    }
    void Start()
    {
        int listensock=listensock_.Fd();
        fd_arry[0]=listensock;
        while(true)
        {
            int maxfd=fd_arry[0];
            // 不能直接accept！检测并获取listensock上面的事件，新连接到来，等价于读事件就绪
            fd_set rfds;
            FD_ZERO(&rfds);
            for(int i=0;i<fd_num_max;i++)
            {
                if(fd_arry[i]==defaultfd) continue;
                FD_SET(fd_arry[i],&rfds);
                if(fd_arry[i]>maxfd)
                {
                    maxfd=fd_arry[i];
                    lg(Info,"get a maxfd: %d",maxfd);
                }
            }
            struct timeval timeout={1,0};
            // 如果事件就绪，上层不处理，select会一直通知你！
            // select告诉你就绪了，接下来的一次读取，我们读取fd的时候，不会被阻塞
            // rfds: 输入输出型参数。 1111 1111 -> 0000 0000
            int n=select(maxfd+1,&rfds,nullptr,nullptr,&timeout);
            switch (n)
            {
            case 0:
                cout << "time out, timeout: " << timeout.tv_sec << "." << timeout.tv_usec << endl;
                break;
            case -1:
                cerr << "select error" << endl;
                break;
            default:
                // 有事件就绪了，TODO
                cout << "get a new link!!!!!" << endl;
                Handler(rfds);
                break;
            }
        }
    }
     void PrintFd()
    {
        cout << "online fd list: ";
        for (int i = 0; i < fd_num_max; i++)
        {
            if (fd_arry[i] == defaultfd)
                continue;
            cout << client_ips[i] << ":" << client_ports[i] << "(fd=" << fd_arry[i] << ") ";
        }
        cout << endl;
    }
    ~SelectServe()
    {}
private:
Sock listensock_;
uint16_t port_;
int fd_arry[fd_num_max];//辅助数组，把sockfd存进数组放到fd_set
string client_ips[fd_num_max];   // 存储对应客户端IP
uint16_t client_ports[fd_num_max];// 存储对应客户端端口
};
